/**
 * WebSocket 管理模块
 * 支持自动重连、心跳、前后台切换等功能
 */

import { WS_URL } from './config.js'

class WebSocketManager {
  constructor() {
    this.ws = null
    this.isConnected = false
    this.isConnecting = false
    this.heartbeatTimer = null
    this.reconnectTimer = null
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectInterval = 3000
    this.heartbeatInterval = 30000
    this.listeners = new Map()
    this.isAppActive = true
    
    // 绑定应用生命周期
    this.bindAppLifecycle()
  }

  /**
   * 连接 WebSocket
   */
  connect(token = '') {
    if (this.isConnected || this.isConnecting) {
      console.log('WebSocket 已连接或正在连接中')
      return
    }

    this.isConnecting = true
    const url = `${WS_URL}/ws?token=${token}`

    console.log('WebSocket 连接中:', url)

    this.ws = uni.connectSocket({
      url,
      success: () => {
        console.log('WebSocket 连接成功')
      },
      fail: (error) => {
        console.error('WebSocket 连接失败:', error)
        this.isConnecting = false
        this.handleReconnect()
      }
    })

    // 监听连接打开
    this.ws.onOpen(() => {
      console.log('WebSocket 连接已打开')
      this.isConnected = true
      this.isConnecting = false
      this.reconnectAttempts = 0
      this.startHeartbeat()
      this.emit('open')
    })

    // 监听消息
    this.ws.onMessage((event) => {
      try {
        const data = JSON.parse(event.data)
        console.log('WebSocket 收到消息:', data)
        this.handleMessage(data)
      } catch (error) {
        console.error('WebSocket 消息解析失败:', error)
      }
    })

    // 监听连接关闭
    this.ws.onClose((event) => {
      console.log('WebSocket 连接关闭:', event)
      this.cleanup()
      this.emit('close', event)
      
      // 如果不是主动关闭，则尝试重连
      if (this.isAppActive && event.code !== 1000) {
        this.handleReconnect()
      }
    })

    // 监听连接错误
    this.ws.onError((error) => {
      console.error('WebSocket 错误:', error)
      this.cleanup()
      this.emit('error', error)
      this.handleReconnect()
    })
  }

  /**
   * 断开连接
   */
  disconnect() {
    console.log('主动断开 WebSocket 连接')
    this.cleanup()
    
    if (this.ws) {
      this.ws.close({
        code: 1000,
        reason: '主动断开'
      })
    }
  }

  /**
   * 发送消息
   */
  send(data) {
    if (!this.isConnected) {
      console.warn('WebSocket 未连接，无法发送消息')
      return false
    }

    try {
      const message = typeof data === 'string' ? data : JSON.stringify(data)
      this.ws.send({
        data: message,
        success: () => {
          console.log('WebSocket 消息发送成功:', data)
        },
        fail: (error) => {
          console.error('WebSocket 消息发送失败:', error)
        }
      })
      return true
    } catch (error) {
      console.error('WebSocket 发送消息异常:', error)
      return false
    }
  }

  /**
   * 添加事件监听器
   */
  on(event, callback) {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, [])
    }
    this.listeners.get(event).push(callback)
  }

  /**
   * 移除事件监听器
   */
  off(event, callback) {
    if (!this.listeners.has(event)) return
    
    const listeners = this.listeners.get(event)
    const index = listeners.indexOf(callback)
    if (index > -1) {
      listeners.splice(index, 1)
    }
  }

  /**
   * 触发事件
   */
  emit(event, data) {
    if (!this.listeners.has(event)) return
    
    this.listeners.get(event).forEach(callback => {
      try {
        callback(data)
      } catch (error) {
        console.error('WebSocket 事件回调异常:', error)
      }
    })
  }

  /**
   * 处理消息
   */
  handleMessage(data) {
    const { type, payload } = data
    
    // 心跳响应
    if (type === 'pong') {
      console.log('收到心跳响应')
      return
    }
    
    // 触发对应事件
    this.emit('message', data)
    this.emit(type, payload)
  }

  /**
   * 开始心跳
   */
  startHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer)
    }

    this.heartbeatTimer = setInterval(() => {
      if (this.isConnected) {
        this.send({ type: 'ping', timestamp: Date.now() })
      }
    }, this.heartbeatInterval)
  }

  /**
   * 停止心跳
   */
  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer)
      this.heartbeatTimer = null
    }
  }

  /**
   * 处理重连
   */
  handleReconnect() {
    if (!this.isAppActive || this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.log('停止重连:', this.isAppActive ? '超过最大重连次数' : '应用不活跃')
      return
    }

    this.reconnectAttempts++
    const delay = this.reconnectInterval * Math.pow(2, this.reconnectAttempts - 1)

    console.log(`WebSocket 重连中... (${this.reconnectAttempts}/${this.maxReconnectAttempts})，${delay}ms 后重试`)

    this.reconnectTimer = setTimeout(() => {
      this.connect()
    }, delay)
  }

  /**
   * 清理资源
   */
  cleanup() {
    this.isConnected = false
    this.isConnecting = false
    this.stopHeartbeat()
    
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
      this.reconnectTimer = null
    }
  }

  /**
   * 绑定应用生命周期
   */
  bindAppLifecycle() {
    // 应用进入前台
    uni.onAppShow(() => {
      console.log('应用进入前台，恢复 WebSocket 连接')
      this.isAppActive = true
      
      if (!this.isConnected && !this.isConnecting) {
        // 延迟重连，等待网络稳定
        setTimeout(() => {
          this.connect()
        }, 1000)
      }
    })

    // 应用进入后台
    uni.onAppHide(() => {
      console.log('应用进入后台，暂停 WebSocket 重连')
      this.isAppActive = false
      this.cleanup()
    })
  }

  /**
   * 获取连接状态
   */
  getStatus() {
    return {
      isConnected: this.isConnected,
      isConnecting: this.isConnecting,
      reconnectAttempts: this.reconnectAttempts,
      isAppActive: this.isAppActive
    }
  }
}

// 创建全局实例
const wsManager = new WebSocketManager()

// 导出实例和类
export default wsManager
export { WebSocketManager }